<?php

namespace App\Http\Controllers;

use App\Models\Media;
use App\Models\Member;
use App\Models\SettingMedia;
use App\Util\Mp4;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\ImageManagerStatic as Image;
use Kuyuan\Phpwidget\File;

class MediaController extends Controller
{
    /**
     * 用户素材库列表
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $_limit = $request->input('limit');
        $_type = $request->input('type');
        $Media = Media::where('member_id',auth('member')->id())
            ->select(["id","type","status","thumb","source"])
            ->offset($_limit[0])
            ->limit($_limit[1])
            ->orderBy('id','desc');
        if($_type == 'image' || $_type == 'video') {
            $Media->where('type',$_type);
        }
        $_data = $Media->get();
        return response(['data'=>$_data]);
    }

    /**
     * 上传素材
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $_type = $request->input('type');
        $File = $request->file('file');
        $_member_id = auth('member')->id();
        $_insert_data = [
            "member_id" => $_member_id,
            "type" => $_type,
            "filename" => $File->getClientOriginalName(),
            "size" => $File->getSize()
        ];
        $_upload_result = [];
        if($_type == 'image'){
            $_upload_result = $this->uploadImage($File);
        } else {
            $_upload_result = $this->uploadVideo($File);
        }
        if(isset($_upload_result['error']) && $_upload_result['error']) {
            return response(
                ['message'=>$_upload_result['message']],
                402
            );
        }
        $_data = $_upload_result["data"];
        $_remote = $_upload_result["remote"];
        $_insert_data = array_merge($_insert_data,$_data);
        $Media = Media::create($_insert_data);
        $_result = [];
        if($Media) {
            $_result = array(
                "id"=>$Media->id,
                "type"=>$_type,
                "status"=>$_insert_data["status"],
                "thumb_url"=> cool_media($_insert_data["thumb"]),
                "source"=> $_data["source"]
            );
            if($_type == "video"){
                $_result["video_url"] = cool_media($_data["source"]);
            }
            // 通知管理员审核
            if(count($_remote) <= 0 && $Media->status == 3) {
                $this->sendCheckNotice('media',$_member_id);
            }
            $_result = array("data"=>$_result,"remote"=>$_remote);
        }
        return response($_result);
    }

    /**
     * 上传图片
     */
    private function uploadImage($File)
    {
        $_data = array(
            "remote" => array(),
            // 数据
            "data" => array(
                "status"=> SettingMedia::value('is_check') ? 3 : 1
            )
        );
        $_relative_path = $File->store(File::stringDir('images'));
        $_data["data"]["source"] = $_relative_path;
        $_data["data"]["thumb"] = File::stringDir('images',$File->getClientOriginalExtension());
        Image::make(public_path('storage/'.$_relative_path))->widen(300,function($constraint) {
            $constraint->upsize();
        })->save(public_path('storage/'.$_data["data"]["thumb"]));
        if(SettingMedia::value('storage') != 'default') {
            $_data["remote"] = [
                $_data["data"]["source"],
                $_data["data"]["thumb"]
            ];
        }
        return $_data;
    }

    /**
     * 上传视频
     */
    private function uploadVideo($File)
    {
        $_data = array(
            // 需要上传远程附件
            "remote" => array(),
            // 数据
            "data" => array(
                "status"=> SettingMedia::value('is_check') ? 3 : 1
            )
        );
        $_relative_path = $File->store(File::stringDir('videos'));
        $Mp4 = new Mp4(public_path('storage/'.$_relative_path));
        $_max_duration = SettingMedia::value("duration");
        if(round($Mp4->_duration) > $_max_duration){
            Storage::delete($_relative_path);
            return array("error"=>true,"message"=>"上传视频长度不能大于".$_max_duration."秒");
        }
        $_thumb_file = File::stringDir('images','jpg');
        Storage::put($_thumb_file,'');
        $_data["data"]["thumb"] = $Mp4->thumb($_thumb_file);
        $_data["data"]["source"] = $_relative_path;
        $_remote = array($_data["data"]["thumb"]);
        if(!SettingMedia::value('transcoding')) {
            $_remote[] = $_relative_path;
        } else {
            $_data["data"]["status"] = 2;
        }
        if(SettingMedia::value('storage') != 'default') {
            $_data["remote"] = $_remote;
        }
        unset($_remote);
        return $_data;
    }

    /**
     * 上传远程图片附件
     * @param array source 要上传的资源
     * @throws \Exception
     * @return mixed
     */
    public function remote(Request $request)
    {
        ignore_user_abort(true);
        set_time_limit(0);
        sleep(10);
        $_source = $request->input('source');
        foreach($_source as $_v){
            cool_upload_remote($_v);
        }
        // 通知管理员审核素材
        if($request->status == 3) {
            $this->sendCheckNotice('media',auth('member')->id());
        }
        return response('success');
    }

    /**
     * 视频转码
     * @param int $_media_id 素材库id
     * @param string $_source 素材本地服务器相对路径
     * @throws \Exception
     */
    public function transcoding($_media_id,Request $request)
    {
        ignore_user_abort(true);
        set_time_limit(0);
        $_source = $request->input('source');
        $_file = public_path('storage/'.$_source);
        $Mp4 = new Mp4($_file);
        $_path = File::stringDir("videos","mp4");
        Storage::put($_path,'');
        try {
            $_path = $Mp4->save($_path);
        } catch (\Exception $e){
            // 转码失败
            Media::where("id",$_media_id)->update(["status"=>4]);
            exit;
        }
        $_size = filesize(public_path('storage/'.$_path));
        @unlink($_file);
        if(SettingMedia::value('storage') != 'default') {
            cool_upload_remote($_path);
        }
        $Media = Media::where("id",$_media_id)
            ->update([
                "source"=>$_path,
                "size" => $_size,
                "status" => SettingMedia::value("is_check") ? 3 : 1
            ]);
        // 通知管理员审核素材
        if($Media->status == 3) {
            $this->sendCheckNotice('media',auth('member')->id());
        }
        return response(['data'=>1]);
    }

    /**
     * 删除素材
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $Media = Media::find($id);
        if(Media::destroy($id)){
            @unlink(Storage::path($Media->source));
            @unlink(Storage::path($Media->thumb));
            cool_delete_remote($Media->source);
            cool_delete_remote($Media->thumb);
        }
        return response(['data'=>$id]);
    }

    /**
     * 获取当前用户内存
     */
    public function memory()
    {
        $_default_size = SettingMedia::value('default_size');
        return response([
            'size'=> $_default_size * 1024 * 1024,
            'sized' => (int) Media::where('member_id',auth('member')->id())->sum('size')
        ]);
    }

    /**
     * 通过一组素材id返回一组素材封面
     * @param Request $request
     * @return mixed
     */
    public function idToThumbs(Request $request)
    {
        $_result = Media::whereIn("id",$request->ids)->pluck('thumb');
        if(count($_result) > 0) {
            foreach($_result as $_k => $_v) {
                $_result[$_k] = cool_media($_v);
            }
        }
        return response(['data'=>$_result]);
    }

    //---------------------------------------------------

    /**
     * 等待审核素材列表
     */
    public function checkList(Request $request)
    {
        $_limit = $request->input('limit', [0,10]);
        $Media = Media::where("status",3)
            ->offset($_limit[0])
            ->limit($_limit[1])
            ->orderBy('id','desc')
            ->get();
        foreach($Media as $item) {
            $item->member;
        }
        return response(["data"=>$Media]);
    }

    /**
     * 等待审核总数
     */
    public function checkTotal()
    {
        return response([
            "data"=>Media::where("status",3)->count()
        ]);
    }

    /**
     * 素材审核通过
     * @param $id
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function pass($id)
    {
        $Media = Media::find($id);
        $Media->status = 1;
        if($Media->save()) {
            if(!$this->sendTplMessage($Media->member_id,true,'素材审核通过')) {
                $this->sendSubscribeMessage($Media->member_id,true,'素材审核通过');
            }
            $_response = response(['data'=>'success']);
        } else {
            $_response = response(['message'=>'操作失败']);
        }
        return $_response;
    }

    /**
     * 删除正在审核的素材
     */
    public function remove($id,Request $request)
    {
        $Media = Media::find($id);
        if(Media::destroy($id)){
            @unlink(Storage::path($Media->source));
            @unlink(Storage::path($Media->thumb));
            cool_delete_remote($Media->source);
            cool_delete_remote($Media->thumb);
            if(!$this->sendTplMessage($Media->member_id,false,$request->remark)) {
                $this->sendSubscribeMessage($Media->member_id,false,$request->remark);
            }
            $_response = response(['data'=>'success']);
        } else {
            $_response = response(['message'=>'删除失败']);
        }
        return $_response;
    }

    /**
     * 发送模板消息
     * @param int $_member_id 会员id
     * @param boolean $_is_pass 是否通过审核
     * @param string $_remark 备注信息
     * @return array|bool|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    private function sendTplMessage($_member_id,$_is_pass,$_remark)
    {
        $Setting = $this->getConfig();
        if(empty($Setting->message->result_check_tpl)) return false;
        $Wechat = $this->wechat();
        $_result = $Wechat->template_message->send([
            'touser' => Member::where("id",$_member_id)->value('openid'),
            'template_id' => $Setting->message->result_check_tpl,
            'url' => route('app'),
            'data' => [
                'first' => [
                    'value' => $Setting->website_name.'-素材审核通知'
                ],
                'keyword1' => [
                    'value' => '管理员'
                ],
                'keyword2' => [
                    'value' => $_is_pass ? '审核通过' : '审核未通过'
                ],
                'keyword3' => [
                    'value' => date('Y-m-d H:i:s')
                ],
                'remark' => [
                    'value' => $_remark
                ]
            ]
        ]);
        if($_result['errcode'] == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 发送订阅消息
     * @param $_member_id
     * @param $_is_pass
     * @param $_remark
     * @return array|bool|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    private function sendSubscribeMessage($_member_id,$_is_pass,$_remark)
    {
        $Setting = $this->getConfig();
        if(empty($Setting->message->result_check_sub)) return false;
        $_data = array(
            "thing10" => array(
                "value" => $Setting->website_name."-素材审核结果"
            ),
            "phrase8" => array(
                "value" => $_is_pass ? "审核通过" : "审核未通过"
            ),
            "thing4" => array(
                "value" => $_remark
            ),
            "time9" => array(
                "value" => date("Y-m-d H:i:s")
            )
        );
        return $this->sendSubscribe(
            $_member_id,
            $Setting->message->result_check_sub,
            $_data,
            route('app')
        );
    }
}
